#ifndef _MIDCODE_H_
#define _MIDCODE_H_

#include "table.h"
#define MIDCODE_NUM 1024
#define STRING_LEN  32

typedef enum Opcode {
    ADD_OP = F_OPCODE, MINUS_OP, MUL_OP, DIV_OP,
    /*LSS, LEQ, GTR, GEQ, NEQ, DEQ,*/
    IFLT_OP, IFLET_OP, IFMT_OP, IFMET_OP,
    IFNE_OP, IFEQ_OP, FUNC_OP,
    ASSIGN_OP, JMP_OP, PARA_OP, CALL_OP, SCANF_OP, PRINTF_OP, 
    RETV_OP, RETN_OP,
} Opcode;

typedef enum OperandType {
    NUM_MB = F_OPERANDTYPE, STR_MB, LVAR_MB, GLOBAL_MB, FUNC_MB, REG_MB, TMPVAR_MB, JUMP_MB,
} OperandType;

typedef union OperandCont {
    int constOp;
    char *stringOp;
    int midcOp;
    NormalElement *varOp;
    NormalElement *tmpOp;
    FuncElement *funcOp;
} OperandCont;

typedef struct Operand {
    OperandType operandType;
    OperandCont operandCont;
} Operand;

typedef struct MidCode {
    /*int addr;*/
    Opcode  op0;
    Operand op1;
    Operand op2;
    Operand op3;
} MidCode;

typedef enum ContType {
    NORMAL_CONT = F_CONTTYPE, FUNC_CONT, CONST_CONT, STRING_CONT, JUMP_CONT,
} ContType;

extern void midcode_init();                               // Init Operand fallback.
extern void mid_move_forward(int step);                   // midcode_table_p += step
extern void enter_midcode(int addr, Opcode op0, Operand op1, Operand op2, Operand op3);
// Set the operand op to desired state.
extern void set_operand(Operand *op, void *em, ContType type);
// Set const operand.
extern void set_const_operand(Operand *op, void *em, TokenType type);
extern void set_last_map();                               // Used for completing the last operation for func_mid_map[]

extern Operand fallback;
extern MidCode midcode_table[/*MIDCODE_NUM*/];
extern int midcode_table_p;

extern const char OpcodeString[][STRING_LEN];             // Const string for printing the opcode.
extern const char OperandTypeString[][STRING_LEN];        // Const string for printing the OperandType
int func_mid_map[/*MAX_FUNC_NUM*/][2];                    // Define the mapping between function and midcode.

#endif